﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace TouchUmlUI
{
    public class OurTabbedConrol : Canvas
    {
        public List<OurTab> Tabs = new List<OurTab>();
        private Line marginLine;
        private static BitmapImage tabbedBackgroundSource;
        private Image[] tabBg;
        private HoverButton addTabButton;
        public static Window1 windowParent;
        private bool drag = false;
        private double ox,oy;
        private double opox = 0;
        public static DependencyProperty TabOffsetX;
        private bool setDelta = false;
        private double deleteDelta = 0.0f;
        private double pox
        {
            get { return (double)this.GetValue(OurTabbedConrol.TabOffsetX); }
            set
            {
                this.SetValue(OurTabbedConrol.TabOffsetX, (double)value);
            }
        }
        private double max_pox = 0.0f;

        public static readonly RoutedEvent OnChangeEvent = EventManager.RegisterRoutedEvent("Change", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(OurTabbedConrol));
        public event RoutedEventHandler Change
        {
            add { AddHandler(OnChangeEvent, value); }
            remove { RemoveHandler(OnChangeEvent, value); }
        }

        public void addOnChange(RoutedEventHandler o)
        {
            Change += o;
        }
        

        public static void poxChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {            
            OurTabbedConrol otc = (OurTabbedConrol)o;
            otc.rearrangeTabs();
        }

        public void tabMouseDown(object sender, MouseButtonEventArgs e)
        {            
            if (e.RightButton == MouseButtonState.Pressed)
            {

                if (SignalR.windowParent.handWrite != null) return;

                OurTab tab = sender as OurTab;
                SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
                UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;
                handWrite.InitializeComponent();
                handWrite.setExistingText(tab.getTitle());


                double sx = 10;
                double sy = 40;
                double nw = 400;
                double nh = 120;
                handWrite.Width = nw;
                handWrite.Height = nh;

                InkCanvas.SetLeft(handWrite, sx);
                InkCanvas.SetTop(handWrite, sy);
                handWrite.Opacity = 1.0f;
                //
                handWrite.bindWithTab(tab);
                SignalR.windowParent.active_canvas.Children.Add(handWrite);
                e.Handled = true;
                /*double l = pox;
                DoubleAnimation anim = new DoubleAnimation(l, 0, new TimeSpan(0, 0, 0, 0, 500));
                anim.DecelerationRatio = 0.9f;
                anim.FillBehavior = FillBehavior.Stop;
                anim.RepeatBehavior = new RepeatBehavior(1);
                anim.Completed += delegate(object o, EventArgs ee)
                {
                    pox = 0;
                };
                this.BeginAnimation(OurTabbedConrol.TabOffsetX, anim);                
                drag = false;*/
            }
            else if (e.LeftButton == MouseButtonState.Pressed) 
            {
                //Console.WriteLine("Drag");
                if (!drag)
                {
                    ox = e.GetPosition(this).X;
                    oy = e.GetPosition(this).Y;
                    opox = (double)this.GetValue(OurTabbedConrol.TabOffsetX);
                    drag = true;
                }
            }
        }

        public void tabMouseUp(object sender, MouseEventArgs e)
        {            
            drag = false;
        }

        public void mouseMove(object sender, MouseEventArgs e)
        {
            if (drag)
            {
                double mx = e.GetPosition(this).X;                
                double dx = mx - ox;
                Console.WriteLine("DX: " + dx+" opox: "+opox+", opox+dx: "+(opox+dx));
                pox = opox + dx;
                if (pox < max_pox)
                {
                    pox = max_pox;
                }
                if (pox > 0) pox = 0;
            }
        }

        static OurTabbedConrol() 
        {            
            OurTabbedConrol.TabOffsetX = DependencyProperty.Register("TabOffsetX", typeof(double), typeof(OurTabbedConrol),new PropertyMetadata(new PropertyChangedCallback(poxChanged)));            
            tabbedBackgroundSource = new BitmapImage();
            tabbedBackgroundSource.BeginInit();
            tabbedBackgroundSource.UriSource = new Uri("ikony\\tabbedbg.png", UriKind.Relative);
            tabbedBackgroundSource.EndInit();            
        }

        public int findByTitle(String a_title)
        {            
            for (int i = 0; i < Tabs.Count; i++)
            {
                if (Tabs[i].getTitle().CompareTo(a_title) == 0)
                {
                    return i;
                }
            }
            return -1;
        }

        public void deleteTab(int id)
        {
            if (SignalR.windowParent.handWrite != null) return;
            OurTab tab = Tabs[id];
            deleteDelta = (int)tab.GetValue(OurTab.ContentWidthProperty);
            int tid = id;            
            if (tab.getTabState() == TabState.SELECTED)
            {
                if (!Select(tid))
                    Select(tid - 1);
            }            
            Tabs.Remove(tab);            
            Refresh();
            setDelta = false;
            rearrangeTabs();
            SignalR.windowParent.fillTabs();
            SignalR.windowParent.treeModelView.Refresh();
        }

        public void deleteTabEvent(object sender, RoutedEventArgs e)
        {
            if (SignalR.windowParent.handWrite != null) return;
            OurTab tab = (((HoverButton)sender).Tag) as OurTab;                        
            deleteDelta = (int)tab.GetValue(OurTab.ContentWidthProperty);            
            int tid = tab.getTabId();
            Tabs[tid].setTabState(TabState.HIDDEN);    
            if (tab.getTabState() == TabState.SELECTED)
            {
                if (!Select(tid))
                    Select(tid - 1);
            }
            tab.setTabState(TabState.HIDDEN);            
//            Tabs.Remove(tab);
            Select(0);
            Refresh();
            setDelta = false;
            rearrangeTabs();
            SignalR.windowParent.fillTabs();
            SignalR.windowParent.treeModelView.Refresh();
        }

        public void addTabEvent(object sender, RoutedEventArgs e)
        {            
            addTab("Nowy diagram "+(getTabsCount() + 1), true);
        }

        public OurTabbedConrol()
        {            
            Tabs.Clear();
            marginLine = new Line();
            marginLine.StrokeThickness = 1;
            marginLine.Stroke = Brushes.White;
            marginLine.X1 = 0; marginLine.X2 = 5000;
            marginLine.Y1 = marginLine.Y2 = 18;
            tabBg = new Image[3];
            for (int i = 0; i < tabBg.Length; i++)
            {
                tabBg[i] = new Image();
                tabBg[i].Source = tabbedBackgroundSource;
                tabBg[i].Width = 991;
                tabBg[i].Height = 36;
                tabBg[i].Stretch = Stretch.UniformToFill;
            }
            addTabButton = new HoverButton("ikony\\icon_addtab.png", "ikony\\icon_addtabhover.png", 33, 23);
            addTabButton.MouseDown += addTabEvent;
            this.Height = 19;
        }

        public void showTabBackgroundShadow(bool show)
        {
            if (show)
            {
                setTabBackgroundHeight(36);
            }
            else
            {
                setTabBackgroundHeight(20);
            }
        }

        private void setTabBackgroundHeight(double aHeight)
        {
            for (int i = 0; i < tabBg.Length; i++)
            {
                tabBg[i].Height = aHeight;
            }
        }

        public OurTab addTab(String a_title, bool refreshAfter)
        {
            if (Tabs == null)
            {
                Tabs = new List<OurTab>();
            }
            setDelta = false;
            OurTab tab = new OurTab(a_title,windowParent.createNewCanvas(),this);
            tab.setTabbedControl(this);
            Tabs.Add(tab);
            if (refreshAfter)
                Refresh();
            SignalR.windowParent.treeModelView.Refresh();
            SignalR.windowParent.fillTabs();
            return tab;
        }

        public bool Select(int n)
        {

            if (SignalR.windowParent.handWrite == null)
            {

                if ((n < 0) || (n >= getTabsCount()))
                    return false;
                if (Tabs[n].getTabState() == TabState.SELECTED)
                    return false;

                foreach (OurTab t in Tabs)
                {
                    if (t.getTabState() == TabState.HIDDEN) continue;
                    t.setTabState(TabState.NOT_SELECTED);
                }

                Tabs[n].Opacity = 1.0f;
                Tabs[n].setTabState(TabState.SELECTED);

                RaiseEvent(new RoutedEventArgs(OurTabbedConrol.OnChangeEvent));

                // change active canvas
                windowParent.changeCanvas(Tabs[n].canvas);
                return true;
            }

            return false;
        }

        public int getVisibleTabsCount()
        {
            int c = 0;
            for (int i = 0; i < Tabs.Count; i++)
            {
                if (Tabs[i].getTabState() != TabState.HIDDEN)
                    c++;
            }
            return c;
        }

        public int getTabsCount()
        {
            return Tabs.Count;
        }

        public int getSelectedId()
        {
            for (int i = 0; i < getTabsCount(); i++)
            {
                if (Tabs[i].getTabState() == TabState.SELECTED)
                {
                    return i;
                }
            }
            return -1;
        }

        public void rearrangeTabs()
        {            
            int ox = (int)pox + (int)deleteDelta;
            deleteDelta = 0;
            int cntWidth = 0;             
            bool canSet = true;
            for (int i = 0; i < getTabsCount(); i++)
            {
                OurTab tab = Tabs[i];
                if (tab.getTabState() == TabState.HIDDEN) continue;

                Canvas.SetLeft(tab, ox);
                int tCnt = (int)tab.GetValue(OurTab.ContentWidthProperty);
                ox = ox + tCnt + 31;
                cntWidth = cntWidth + tCnt + 31;
                if (tCnt <= 0)
                    canSet = false;
            }

            if (!setDelta)
            {
                if (canSet)
                {                    
                    int delta = (int)cntWidth - (int)windowParent.ActualWidth + 45;
                    max_pox = -delta;                    
                    setDelta = true;
                }                
            }

            if (Tabs.Count==1) 
                Canvas.SetLeft(addTabButton, ox + 6);
            else
                Canvas.SetLeft(addTabButton, ox + 4);
        }

        public void Refresh()
        {            
            int ox = 0;
            this.Children.Clear();
            for (int i = 0; i < tabBg.Length; i++)
            {
                Canvas.SetTop(tabBg[i], -3);
                Canvas.SetLeft(tabBg[i], i * 991);
                Children.Add(tabBg[i]);
            }
            int selId = getSelectedId();
            for (int i = 0; i < getTabsCount(); i++)
            {
                OurTab tab = Tabs[i];
                if (tab.getTabState() == TabState.HIDDEN) continue;
                tab.Opacity = 0.7f;
                tab.SetId(i);                
                Canvas.SetLeft(tab, ox);
                tab.Refresh();                
                Children.Add(tab);
                ox = ox + tab.contentWidth - 15;
            }
            if (selId >= 0)
            {
                Children.Remove(Tabs[selId]);
                Children.Add(Tabs[selId]);
            }
            Children.Add(marginLine);
            Canvas.SetLeft(addTabButton, ox + 4);
            Canvas.SetTop(addTabButton, -2);
            Children.Add(addTabButton);
        }


        public void Clear()
        {
            Select(0);
            foreach (OurTab tab in Tabs)
            {
                tab.canvas.Children.Clear();
                if (tab.canvas is OurCanvas)
                    ((OurCanvas)tab.canvas).al.Clear();
            }
            Tabs.Clear();            
        }
    }
}
